/**
 * SpriteArgs.java
 *
 */

package gamepack;

import java.awt.Rectangle;
import java.awt.Image;
import java.util.*;
/**
 *
 */
 
class ParseHelper {

	public Map<String,String> strMap = new HashMap();
	public Map<String,String[]> strArrMap = new HashMap();

		public ParseHelper(String s) {
			String[] parts = s.split(",");
			for(int i=0; i<parts.length; i++ ) {
				String[] subpart = parts[i].split("=");	
				if( subpart == null || subpart.length < 2 ) continue;				
				String name = subpart[0].trim();
				String value = subpart[1].trim();
				if( name.endsWith("[]") ) {
				     //System.out.println("\n-------" + value );
					String[] valArray = value.split("\\|");
					//System.out.println("\n---len=" + valArray.length );
					for ( int j=0;j<valArray.length;j++) {
						valArray[j] = valArray[j].trim();
					}
					//System.out.println("\nvalArray=" + SpriteArgs.toString(valArray) );
					strArrMap.put( name,valArray );
				} else {
					strMap.put( name,value );
				}
			}
		}
}

public class SpriteArgs {

       // For Attributes in Sprite Class
       public int x,y,z,type,curFrame;
       public int dir,vx,vy,health;	   
       public String[] attributes;
       public String[] blockers;
       public String[] colliders;
       public boolean visible;

	   // Optional
	   public String spriteName;
	   
       // For further attributes in Derived class       
       public Map<String,String> strMap = null;
	   public Map<String,String[]> strArrMap = null; //new HashMap();
	   
	   // If passing Object as Argument is needed // May need to revisit design here..
	   public Sprite spr;

	   public static String toString(String[] arr) {
		if (arr == null) return null;
		StringBuffer buf = new StringBuffer(); 
		for(int i=0;i<arr.length;i++) {
			buf.append(arr[i] );			
			if( i != arr.length-1 )
			buf.append("|");
		}
		return buf.toString();
	   }
	   
	   
	   
	    public static String toString(Map<String,Vector<Sprite> > mp,int dummy) { // to display Environment.familyOfAttributes. adhoc
		   if( mp == null ) return null;
			StringBuffer buf = new StringBuffer(); 
	       Iterator it = mp.entrySet().iterator();
		while (it.hasNext()) {
			Map.Entry pairs = (Map.Entry)it.next();
			String name= (String) pairs.getKey();
			Vector<Sprite> vecSpr= (Vector<Sprite>) pairs.getValue();
			StringBuffer sprDetails = new StringBuffer();
			for(int i=0;i<vecSpr.size();i++) {
				sprDetails.append( "blah" );
				sprDetails.append(",");
			}
			buf.append(name+"="+ vecSpr.size() +"|");
		}
		if( buf.length() > 0 ) buf.deleteCharAt( buf.length()-1 );
		return buf.toString();
	   }
	   
	   
	   public static String toString(Map<String,String> mp) {
		   if( mp == null ) return null;
			StringBuffer buf = new StringBuffer(); 
	       Iterator it = mp.entrySet().iterator();
		while (it.hasNext()) {
			Map.Entry pairs = (Map.Entry)it.next();
			String name= (String) pairs.getKey();
			String value= (String) pairs.getValue();
			buf.append(name+"="+value+"|");
		}
		if( buf.length() > 0 ) buf.deleteCharAt( buf.length()-1 );
		return buf.toString();
	   }

	   public static String toStringArr(Map<String,String[]> mp) {
		   if( mp == null ) return null;
			StringBuffer buf = new StringBuffer(); 
			buf.append("{");
	       Iterator it = mp.entrySet().iterator();
		while (it.hasNext()) {
			Map.Entry pairs = (Map.Entry)it.next();
			String name= (String) pairs.getKey();
			String[] value= (String[]) pairs.getValue();
			buf.append(name+"="+SpriteArgs.toString(value)+",");
		}
		if( buf.length() > 1 ) buf.deleteCharAt( buf.length()-1 );
		buf.append("}");
		
		return buf.toString();
	   }
	   	   
       public String toString() { 
		
		String s = "*x="+x+"," + "y="+y+"," + "z="+z+"," + "type="+type+"," + "curFrame="+curFrame+"," + "dir="+dir+","
                  +"vx="+vx+"," + "vy="+vy+"," + "visible="+visible+"\n" 
				  + "attributes[]=" + toString(attributes) + ","
				  + "blockers[]=" + toString(blockers) + ","
				  + "colliders[]=" + toString(colliders) + ","
				  + "strMap[]=" + toString(strMap) + ","
				  + "strArrMap[]=" + toStringArr(strArrMap);
		return s;
	   }


		public void set(int x,int y,int type,int curFrame,
	              String[] attributes_,String[] blockers,String[] colliders,
	              int dir,boolean visible,int vx,int vy, 
				  Map<String,String> strMap, Map<String,String[]> strArrMap, Sprite sprObj ) {
			this.x = x;  
 		    this.y = y;
		    this.z = z;
		    this.type = type;
		    this.curFrame = curFrame;		    
		    this.attributes = attributes;
		    this.blockers = blockers;
		    this.colliders = colliders;
		    this.dir = dir;
		    this.visible = visible;
		    this.vx = vx;
		    this.vy = vy;
		    this.health = health;
		
			this.strMap = strMap;
			this.strArrMap = strArrMap;
			this.spr = sprObj;		  
		}

       public SpriteArgs(String formatStr) {
              set(formatStr,null);
       }

       public SpriteArgs() {  }
	   	   
	   public SpriteArgs(String formatStr, Sprite spr) {
			set(formatStr,spr);
	   }
	   
	   // Improvise and standardize!! interface of SpriteArgs
	   public static SpriteArgs create(String spawnString, Sprite spr)  { // Input param is complete spawn string.
			int index = spawnString.indexOf('#');
			String part1 = spawnString.substring( 0 , index);
			String part2 = spawnString.substring(index+1, spawnString.length() );
			SpriteArgs sa = new SpriteArgs(part2.trim(),spr);
			sa.spriteName = part1.trim();
			return sa;
	   }
	   
     public void set(String spawnString, Sprite spr) {
	   
	    String[] Parts = spawnString.split("#");   // Will split into 2 parts - reservedAttrib and optionalAttrib
		
		ParseHelper reservedAttrib = new ParseHelper( Parts[0] );		
		
		try {
		
		if( reservedAttrib.strMap.containsKey("x") ) {
			x = Integer.parseInt( reservedAttrib.strMap.get("x") );			
		} else x=0;
		if( reservedAttrib.strMap.containsKey("y") ) {
			y = Integer.parseInt( reservedAttrib.strMap.get("y") );			
		} else y=0;
		if( reservedAttrib.strMap.containsKey("z") ) {
			z = Integer.parseInt( reservedAttrib.strMap.get("z") );			
		} else z=0;
		if( reservedAttrib.strMap.containsKey("type") ) {
			type = Integer.parseInt( reservedAttrib.strMap.get("type") );			
		} else type=0;
		if( reservedAttrib.strMap.containsKey("curFrame") ) {
			curFrame = Integer.parseInt( reservedAttrib.strMap.get("curFrame") );			
		} else curFrame = 0;
		if( reservedAttrib.strMap.containsKey("dir") ) {
			dir = Integer.parseInt( reservedAttrib.strMap.get("dir") );			
		} else dir = 0;
		if( reservedAttrib.strMap.containsKey("visible") ) {
			visible = reservedAttrib.strMap.get("visible").equals("true") ? true : false;			
		} else visible = true;
		if( reservedAttrib.strMap.containsKey("dir") ) {
			dir = Integer.parseInt( reservedAttrib.strMap.get("dir") );			
		} else dir = 0;
		if( reservedAttrib.strMap.containsKey("vx") ) {
			vx = Integer.parseInt( reservedAttrib.strMap.get("vx") );			
		} else vx = 0;
		if( reservedAttrib.strMap.containsKey("vy") ) {
			vy = Integer.parseInt( reservedAttrib.strMap.get("vy") );			
		} else vy = 0;
		if( reservedAttrib.strMap.containsKey("health") ) {
			health = Integer.parseInt( reservedAttrib.strMap.get("health") );			
		} else health = 0;
		//--------------------------------------------------------
		if( reservedAttrib.strArrMap.containsKey("attributes[]") ) {
			attributes = reservedAttrib.strArrMap.get("attributes[]");			
		} else attributes = null;
		if( reservedAttrib.strArrMap.containsKey("blockers[]") ) {
			blockers = reservedAttrib.strArrMap.get("blockers[]");			
		} else blockers = null;
		if( reservedAttrib.strArrMap.containsKey("colliders[]") ) {
			colliders = reservedAttrib.strArrMap.get("colliders[]");			
		} else colliders = null;

		//--- Optional fields -------------------------------------
		if( Parts.length >= 2 ) {
			ParseHelper optionalAttrib = new ParseHelper( Parts[1] );
			strMap = optionalAttrib.strMap;
			strArrMap = optionalAttrib.strArrMap;			
		} else {
			strMap = null;
			strArrMap = null;
		}
		}
		catch( NumberFormatException e) { 
			throw new RuntimeException("NumberFormatException().getCause() = " + e.getMessage() +"\n Check spawn string for Error \"" + spawnString + "\"");
		}
		this.spr = spr;

	   }
		public String get(String s) {
			return strMap.get(s);
		}
		
		public String[] getArray(String s) {
			return strArrMap.get(s);
		}
		
		public int getAsInt(String s) {
			return Integer.parseInt( get(s) );
		}
		
		public double getAsDouble( String s) {
			return Double.parseDouble( get(s) );
		}
			
		
		public int[] getArrayAsInt(String s) {
			String[] str_arr = getArray( s );
			int[] int_arr = new int[str_arr.length];
			
			for( int i=0;i<str_arr.length;i++ ) {
				int_arr[i] = getAsInt( str_arr[i] );
			}
			return int_arr;
		}
		
}